// This MFC Samples source code demonstrates using MFC Microsoft Office Fluent User Interface 
// (the "Fluent UI") and is provided only as referential material to supplement the 
// Microsoft Foundation Classes Reference and related electronic documentation 
// included with the MFC C++ library software.  
// License terms to copy, use or distribute the Fluent UI are available separately.  
// To learn more about our Fluent UI licensing program, please visit 
// http://msdn.microsoft.com/officeui.
//
// Copyright (C) Microsoft Corporation
// All rights reserved.

#include "stdafx.h"
#include "MainFrame.h"
#include "MessageListPane.h"
#include "Resource.h"
#include "WindowsGui.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

using namespace System;
using namespace System::Collections;
using namespace KingOfCSharp::iHunter;


ref class MessageEnumerator: public IEnumerator
{

private:
	POSITION pos;
	CMessageListCtrl *owner;
	int nItem;
public:
	MessageEnumerator(CMessageListCtrl *owner)
	{
		pos = owner->GetFirstSelectedItemPosition();
		this->owner = owner;
		nItem = -1;
	}

	~MessageEnumerator()
	{
	}

	virtual bool MoveNext(void)
	{
		POSITION p = this->pos;
		nItem =  owner->GetNextSelectedItem(p);
		if (pos == NULL)
		{
			nItem = -1;
			return false;
		}
		else
		{
			this->pos = p;
			return true;
		}
	}
	virtual void Reset(void)
	{
		pos = owner->GetFirstSelectedItemPosition();
	}


	virtual property Object ^ Current 
	{
		Object ^ get()
		{
			if (nItem < 0)
				throw gcnew InvalidOperationException();

			LPARAM lParam = owner->GetItemData(nItem);
			Guid * lpGuid = reinterpret_cast<Guid *>(lParam);

			return cli::safe_cast<Object ^>(*lpGuid);
		}
	}
};

ref class MessageEnumerable: IEnumerable
{
private:
	CMessageListCtrl *owner;
public:
	MessageEnumerable(CMessageListCtrl * owner)
	{
		this->owner = owner;
	}
	virtual IEnumerator ^ GetEnumerator()
	{
		return gcnew MessageEnumerator(owner);
	}
};
/////////////////////////////////////////////////////////////////////////////
// CFileView

CMessageListPane::CMessageListPane()
{
}

CMessageListPane::~CMessageListPane()
{
}

BEGIN_MESSAGE_MAP(CMessageListPane, CDockablePane)
	ON_WM_CREATE()
	ON_WM_SIZE()
	ON_WM_CONTEXTMENU()
	ON_WM_PAINT()
	ON_WM_SETFOCUS()
	ON_COMMAND(ID_VIEW_GROUPBYTITLE, &CMessageListPane::OnViewGroupbytitle)
	ON_COMMAND(ID_VIEW_GROUPBYTIME, &CMessageListPane::OnViewGroupbytime)
	ON_COMMAND(ID_VIEW_GROUPBYAUTHOR, &CMessageListPane::OnViewGroupbyauthor)
	ON_COMMAND(ID_VIEW_UNREADONLY, &CMessageListPane::OnViewUnreadonly)
	ON_UPDATE_COMMAND_UI(ID_VIEW_GROUPBYTITLE, &CMessageListPane::OnUpdateViewGroupbytitle)
	ON_UPDATE_COMMAND_UI(ID_VIEW_GROUPBYAUTHOR, &CMessageListPane::OnUpdateViewGroupbyauthor)
	ON_UPDATE_COMMAND_UI(ID_VIEW_GROUPBYTIME, &CMessageListPane::OnUpdateViewGroupbytime)
	ON_UPDATE_COMMAND_UI(ID_VIEW_UNREADONLY, &CMessageListPane::OnUpdateViewUnreadonly)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CWorkspaceBar message handlers

int CMessageListPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
{

	if (CDockablePane::OnCreate(lpCreateStruct) == -1)
		return -1;

	CRect rectDummy;
	rectDummy.SetRectEmpty();

	// Create view:
	const DWORD dwViewStyle = WS_CHILD | WS_VISIBLE;

	if (!m_wndMessageList.Create(dwViewStyle, rectDummy, this, IDR_MESSAGE_LIST))
	{
		TRACE0("Failed to create file view\n");
		return -1;      // fail to create
	}

	

	m_wndToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE |CBRS_TOOLTIPS , IDR_MESSAGE_LIST);
	m_wndToolBar.LoadToolBar(IDR_MESSAGE_LIST, 0, 0, TRUE /* Is locked */);

	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() | CBRS_TOOLTIPS | CBRS_FLYBY);

	m_wndToolBar.SetPaneStyle(m_wndToolBar.GetPaneStyle() & ~(CBRS_GRIPPER | CBRS_SIZE_DYNAMIC | CBRS_BORDER_TOP | CBRS_BORDER_BOTTOM | CBRS_BORDER_LEFT | CBRS_BORDER_RIGHT));

	m_wndToolBar.SetOwner(this);

	// All commands will be routed via this control , not via the parent frame:
	m_wndToolBar.SetRouteCommandsViaFrame(FALSE);

	//theApp.GetContextMenuManager()->AddMenu(_T("Messages222"), IDR_POPUP_MESSAGES);
	// Fill in some static tree view data (dummy code, nothing magic here)
	AdjustLayout();

	return 0;
}

void CMessageListPane::OnSize(UINT nType, int cx, int cy)
{
	CDockablePane::OnSize(nType, cx, cy);
	AdjustLayout();
}

void CMessageListPane::OnContextMenu(CWnd* pWnd, CPoint point)
{
	if (pWnd->GetSafeHwnd() != m_wndMessageList.GetSafeHwnd())
	{
		CDockablePane::OnContextMenu(pWnd, point);
	}
	else
	{
		// Select clicked item:
		CPoint ptTree = point;
		m_wndMessageList.ScreenToClient(&ptTree);

		UINT flags = 0;
		int nItem = m_wndMessageList.HitTest(ptTree, &flags);
		if (nItem != -1)
		{
			m_wndMessageList.SetItemState(nItem,LVIS_SELECTED,LVIS_SELECTED);
			m_wndMessageList.SetFocus();
			VERIFY(theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_MESSAGES,point.x,point.y,this));
		}
	}
}

void CMessageListPane::AdjustLayout()
{
	if (GetSafeHwnd() == NULL)
	{
		return;
	}

	CRect rectClient;
	GetClientRect(rectClient);

	int cyTlb = m_wndToolBar.CalcFixedLayout(FALSE, TRUE).cy;

	m_wndToolBar.SetWindowPos(NULL, rectClient.left, rectClient.top, rectClient.Width(), cyTlb, SWP_NOACTIVATE | SWP_NOZORDER);
	m_wndMessageList.SetWindowPos(NULL, rectClient.left + 1, rectClient.top + cyTlb + 1, rectClient.Width() - 2, rectClient.Height() - cyTlb - 2, SWP_NOACTIVATE | SWP_NOZORDER);
}

void CMessageListPane::OnProperties()
{
	AfxMessageBox(_T("Properties...."));

}


void CMessageListPane::OnPaint()
{
	CPaintDC dc(this); // device context for painting

	CRect rectTree;
	m_wndMessageList.GetWindowRect(rectTree);
	ScreenToClient(rectTree);

	rectTree.InflateRect(1, 1);
	dc.Draw3dRect(rectTree, ::GetSysColor(COLOR_3DSHADOW), ::GetSysColor(COLOR_3DSHADOW));
}

void CMessageListPane::OnSetFocus(CWnd* pOldWnd)
{
	CDockablePane::OnSetFocus(pOldWnd);

	m_wndMessageList.SetFocus();
}




void CMessageListPane::OpenFolder(KingOfCSharp::iHunter::IFolder ^folder)
{
	IFolder ^f = theApp.m_clrClient->FindFolderByGuid(folder->Guid);
	CString strTemp;
	if (f == nullptr)
	{
		return;
	}
	if (f->IsSpecialFolder)
	{
		if (f->Name == L"[Root]")
		{
			strTemp.LoadString(IDS_FOLDERS_ROOT);
		}
		else if (folder->Name == L"[Inbox]")
		{
			strTemp.LoadString(IDS_FOLDERS_INBOX);
		}
		else if (folder->Name == L"[Outbox]")
		{
			strTemp.LoadString(IDS_FOLDERS_OUTBOX);
		}
		else if (folder->Name == L"[Drafts]")
		{
			strTemp.LoadString(IDS_FOLDERS_DRAFTS);
		}
		else if (folder->Name == L"[Sent]")
		{
			strTemp.LoadString(IDS_FOLDERS_SENTS);
		}
		else if (folder->Name == L"[Deleted]")
		{
			strTemp.LoadString(IDS_FOLDERS_DELETED);
		}
		else
		{
			strTemp = MarshalUtils::GetMFCString(f->Name);
		}
	}
	else
	{
		strTemp = MarshalUtils::GetMFCString(f->Name);
	}

	this->SetWindowText(strTemp);

	this->m_wndMessageList.OpenFolder(folder);
}

IEnumerable ^CMessageListPane::GetSelectedMessageGuids()
{
	return gcnew MessageEnumerable(&m_wndMessageList);
}

void CMessageListPane::ShowSearchResult()
{
	this->SetWindowText(_T("Search Result"));;
	this->m_wndMessageList.ShowSearchResult();
}

void CMessageListPane::OnViewGroupbytitle()
{
	if (m_wndMessageList.m_iGroupMode == ML_GROUPBY_TITLE)
		m_wndMessageList.m_iGroupMode = ML_GROUPBY_NONE;
	else
		m_wndMessageList.m_iGroupMode = ML_GROUPBY_TITLE;

	m_wndMessageList.Refresh();
}

void CMessageListPane::OnViewGroupbytime()
{
	if (m_wndMessageList.m_iGroupMode == ML_GROUPBY_TIME)
		m_wndMessageList.m_iGroupMode = ML_GROUPBY_NONE;
	else
		m_wndMessageList.m_iGroupMode = ML_GROUPBY_TIME;

	m_wndMessageList.Refresh();
}

void CMessageListPane::OnViewGroupbyauthor()
{
	if (m_wndMessageList.m_iGroupMode == ML_GROUPBY_AUTHOR)
		m_wndMessageList.m_iGroupMode = ML_GROUPBY_NONE;
	else
		m_wndMessageList.m_iGroupMode = ML_GROUPBY_AUTHOR;

	m_wndMessageList.Refresh();
}

void CMessageListPane::OnViewUnreadonly()
{
	m_wndMessageList.m_bShowUnreadOnly = !m_wndMessageList.m_bShowUnreadOnly;
	
	m_wndMessageList.Refresh();
}

void CMessageListPane::OnUpdateViewGroupbytitle(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck((m_wndMessageList.m_iGroupMode == ML_GROUPBY_TITLE)?(1):(0));
}

void CMessageListPane::OnUpdateViewGroupbyauthor(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck((m_wndMessageList.m_iGroupMode == ML_GROUPBY_AUTHOR)?(1):(0));
}

void CMessageListPane::OnUpdateViewGroupbytime(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck((m_wndMessageList.m_iGroupMode == ML_GROUPBY_TIME)?(1):(0));
}

void CMessageListPane::OnUpdateViewUnreadonly(CCmdUI *pCmdUI)
{
	pCmdUI->SetCheck((m_wndMessageList.m_bShowUnreadOnly)?(1):(0));
}
